package com.pignest.hotel.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.pignest.framework.json.JsonArray;
import com.pignest.framework.json.JsonObject;
import com.pignest.framework.util.Utils;
import com.pignest.hotel.beans.Card;
import com.pignest.hotel.beans.Duty;
import com.pignest.hotel.beans.DutyLog;
import com.pignest.hotel.beans.Log;
import com.pignest.hotel.service.AdminService;
import com.pignest.hotel.service.CardService;
import com.pignest.hotel.spring.ContextHolder;
import com.pignest.hotel.spring.Services;
import com.pignest.hotel.util.DateUtil;

public class QueryServlet extends HttpServlet {
	private static final long serialVersionUID = -5176105545759444331L;
	public static final String FILTER = "query";
	private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm";
		
	public String listLogs(HttpServletRequest request) {
		String userName = request.getParameter("userName");
		String startTime = request.getParameter("startTime");
		String endTime = request.getParameter("endTime");
		String ip = request.getParameter("ip");
		String keyword = request.getParameter("keyword");
		int pageIndex = Utils.getInteger(request.getParameter("page"), 1) - 1;
		int pageSize = Utils.getInteger(request.getParameter("rp"), 10);
		
		Date start = DateUtil.toDate(startTime, DATE_FORMAT);
		Date end = DateUtil.toDate(endTime, DATE_FORMAT);
		AdminService service = Services.getAdminService();
		int count = service.countLogs(userName, start, end, ip, keyword);
		List<Log> logs = count > 0 ? service.listLogs(userName, start, end, ip, keyword, "time desc", pageSize, pageIndex) : null;
		JsonObject r = new JsonObject();
		r.put("page", pageIndex + 1);
		r.put("total", count);
		if (logs == null)
			return r.toExternalRepresentation();
		JsonArray rows = new JsonArray();
		for (Log log : logs) {
			JsonObject row = new JsonObject();
			row.put("id", log.getId());
			JsonArray cell = new JsonArray();
			cell.add(log.getUserName(), DateUtil.toString(log.getTime()), log.getIp(), log.getAction(), log.getCategory(), log.getDescription());
			row.put("cell", cell);
			rows.add(row);
		}
		r.put("rows", rows);
//		System.out.println(r.toExternalRepresentation());
		return r.toExternalRepresentation();
	}

	public String listDuties(HttpServletRequest request) {
		String userName = request.getParameter("userName");
		String status = request.getParameter("status");
		int pageIndex = Utils.getInteger(request.getParameter("page"), 1) - 1;
		int pageSize = Utils.getInteger(request.getParameter("rp"), 10);
		
		int state = Utils.getInteger(status, -1);
		AdminService service = Services.getAdminService();
		int count = service.countDuties(userName, state);
		List<Duty> duties = count > 0 ? service.listDuties(userName, state, "startTime desc", pageSize, pageIndex) : null;
		JsonObject r = new JsonObject();
		r.put("page", pageIndex + 1);
		r.put("total", count);
		if (duties == null)
			return r.toExternalRepresentation();
		JsonArray rows = new JsonArray();
		for (Duty duty : duties) {
			JsonObject row = new JsonObject();
			row.put("id", duty.getId());
			JsonArray cell = new JsonArray();
			cell.add(duty.getUser().getName(), duty.getStatus2(), DateUtil.toString(duty.getStartTime()), DateUtil.toString(duty.getEndTime()));
			cell.add((String)(duty.getPreviousUser() == null ? null : duty.getPreviousUser().getName()));
			cell.add(Utils.toPrice(duty.getStartCash()));
			cell.add(Utils.toPrice(duty.getEndCash()));
			cell.add(Utils.toPrice(duty.getWithdraw()));
			row.put("cell", cell);
			rows.add(row);
		}
		r.put("rows", rows);
//		System.out.println(r.toExternalRepresentation());
		return r.toExternalRepresentation();
	}
	
	public String listCards(HttpServletRequest request) {
		int type = Utils.getInteger(request.getParameter("type"), -1);
		int status = Utils.getInteger(request.getParameter("status"), 0);
		String cardNumber = request.getParameter("cardNumber");
		String holderName = request.getParameter("holderName");
		String serialNumber = request.getParameter("serialNumber");
		String expireTime = request.getParameter("expireTime");
		
		int pageIndex = Utils.getInteger(request.getParameter("page"), 1) - 1;
		int pageSize = Utils.getInteger(request.getParameter("rp"), 10);
		
		Boolean e = null;
		Boolean granted = null;
		if (status == 1)
			e = Boolean.TRUE;
		else if (status == 2)
			e = Boolean.FALSE;
		else if (status == 3)
			granted = Boolean.TRUE;
		else if (status == 4)
			granted = Boolean.FALSE;
		Date expire = DateUtil.toDate(expireTime, "");
		CardService service = Services.getCardService();
		int count = service.countCards(type, e, cardNumber, holderName, serialNumber, expire);
		List<Card> duties = count > 0 ? service.listCards(type, e, granted, cardNumber, holderName, serialNumber, expire, null, pageSize, pageIndex) : null;
		JsonObject r = new JsonObject();
		r.put("page", pageIndex + 1);
		r.put("total", count);
		if (duties == null)
			return r.toExternalRepresentation();
		JsonArray rows = new JsonArray();
		for (Card card : duties) {
			JsonObject row = new JsonObject();
			row.put("id", card.getId());
			JsonArray cell = new JsonArray();
			cell.add(card.getCardNumber(), card.getType2(), card.getEnable2(), card.getHolderName(), card.getSerialNumber(), card.getExpireTime3());
			row.put("cell", cell);
			rows.add(row);
		}
		r.put("rows", rows);
//		System.out.println(r.toExternalRepresentation());
		return r.toExternalRepresentation();
	}
	
	public String listDutyLogs(HttpServletRequest request) {
		String dutyId = request.getParameter("duty");
		int pageIndex = Utils.getInteger(request.getParameter("page"), 1) - 1;
		int pageSize = Utils.getInteger(request.getParameter("rp"), 10);
		AdminService service = Services.getAdminService();
		int count = service.countDutyLogs(dutyId);
		List<DutyLog> duties = count > 0 ? service.listDutyLogs(dutyId, pageSize, pageIndex) : null;
		JsonObject r = new JsonObject();
		r.put("page", pageIndex + 1);
		r.put("total", count);
		if (duties == null)
			return r.toExternalRepresentation();
		JsonArray rows = new JsonArray();
		for (DutyLog log : duties) {
			JsonObject row = new JsonObject();
			row.put("id", log.getId());
			JsonArray cell = new JsonArray();
			cell.add(DateUtil.toString(log.getTime(), DateUtil.HOTEL_DEFAULT_FORMAT));
			cell.add(log.getAction());
			cell.add(Utils.toPrice(log.getMoney()));
			cell.add(log.getMoney() == 0 ? null : log.getMethod());
			cell.add(log.getDescription());
			row.put("cell", cell);
			rows.add(row);
		}
		r.put("rows", rows);
//		System.out.println(r.toExternalRepresentation());
		return r.toExternalRepresentation();
	}
	
	private CharSequence dispatch(String type, HttpServletRequest req) {
		if ("log".equals(type)) {
			return listLogs(req);
		} else if ("duty".equals(type)) {
			return listDuties(req);
		} else if ("card".equals(type)) {
			return listCards(req);
		} else if ("dutylog".equals(type)) {
			return listDutyLogs(req);
		}
		return null;
	}

	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String type = getQueryType(req.getRequestURI());
		if (type == null)
			return;
		CharSequence r = dispatch(type, req);
		if (r == null)
			return;
		PrintWriter writer = resp.getWriter();
		writer.write(r.toString());
	}
	
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
	
	private String getQueryType(String uri) {
		String[] ss = StringUtils.split(uri.substring(ContextHolder.getContextPath().length()), '/');
		if (ss == null || ss.length != 2)
			return null;
		if (!ss[0].equals(FILTER))
			return null;
		return ss[1];
	}
}
